package fm.cheyiwang.controller;

import com.alibaba.fastjson.JSON;
import com.mongodb.DBObject;
import fm.controller.BaseController;
import fm.dto.NeiyiUser;
import fm.entity.*;
import fm.entityEnum.ArticleAdEnum;
import fm.entityEnum.ClientTypeEnum;
import fm.entityEnum.ProductTypeEnum;
import fm.exception.BizException;
import fm.mongo.MCondition;
import fm.mongo.MRel;
import fm.util.CommonUtils;
import fm.web.CurrentRequest;
import fm.web.MediaTypes;
import fm.yichenet.dto.ArticleDto;
import fm.yichenet.mongo.service.ArticleService;
import fm.yichenet.service.OrderService;
import fm.yichenet.service.SectionService;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * Created by 宏炜 on 2017-05-28.
 */
@Controller
@RequestMapping("/article")
public class ArticleController extends BaseController {

    @Autowired
    ArticleService articleService;

    /**
     * 获取图文文章列表
     *
     * @param pageNum
     * @param pageSize
     * @param section_id
     * @param keyword
     * @param modelMap
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "getArticleList", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String getArticleList(@RequestParam(value = "pageNum", required = true) Integer pageNum,
                                 @RequestParam(value = "pageSize", required = true) Integer pageSize,
                                 @RequestParam(value = "section_id", required = false) Long section_id,
                                 @RequestParam(value = "keyword", required = false) String keyword,
                                 @RequestParam(value = "user_id", required = false) String user_id,
                                 ArticleAdEnum flags,
                                 Long timestamp, ModelMap modelMap) throws Exception {
        modelMap.clear();
        try {
            MCondition mc = MCondition.create(MRel.and);
            if (StringUtils.isNotEmpty(keyword)) {
                MCondition keywordMatchCondition = MCondition.create(MRel.or);
                keywordMatchCondition.append(MCondition.create(MRel.regex).append("main_title", Pattern.compile(keyword)));
                keywordMatchCondition.append(MCondition.create(MRel.regex).append("sub_title", Pattern.compile(keyword)));
                keywordMatchCondition.append(MCondition.create(MRel.regex).append("content", Pattern.compile(keyword)));
                mc.append(keywordMatchCondition);
            }
            if (timestamp != null) {
                mc.append(MCondition.create(MRel.lte).append("create_time", new Date(timestamp)));
            }
            if (flags != null) {
                mc.append(MCondition.create(MRel.exists).append("ad_option." + flags.toString(), true));
            }

            if (!CommonUtils.isEmpty(section_id)) {
                mc.append("section_id", section_id);
            }

            if (StringUtils.isNotEmpty(user_id)) {
                mc.append("user_id",user_id);
            }

            LOGGER.info("图文／文章列表查询条件:{}", mc.toDBObject().toString());
            Map param = mc.toDBObject().toMap();
            if (StringUtils.isEmpty(keyword) && section_id == null && timestamp == null) {
                param = new HashMap();
            }
            Map<String, Object> data = new HashedMap();
            List<DBObject> articles = articleService.getArticleForPage(param, pageSize, pageNum);
            for (DBObject article : articles) {
                Long comments_count = articleService.countComments(String.valueOf(article.get("id")), 1);
                Long likes_count = articleService.countComments(String.valueOf(article.get("id")), 0);
                article.put("comments_count", comments_count);
                article.put("likes_count", likes_count);
            }
            Long total = articleService.countArticles(param);
            data.put("articles", articles);
            data.put("total", total);
            modelMap.put("data", data);
            this.success(modelMap);
        } catch (BizException ex) {
            this.failed(modelMap, ex);
        }
        return JSON.toJSONString(modelMap);
    }


    @Autowired
    SectionService sectionService;

    @Autowired
    OrderService orderService;

    /**
     * 发布更新图文
     *
     * @param articleDto
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "mergeArticle", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String mergeArticle(@RequestBody ArticleDto articleDto, HttpServletRequest request) throws Exception {
        Map res = new HashMap();
        try {
            Map data = new HashMap();
            articleDto.setType(0);
            DBObject article = articleService.mergeArticle(articleDto);


            Section section = sectionService.getById((Long) article.get("section_id"));
            SectionPayResolve resolve = null;
            String resolveKey = articleDto.getTimeRange();
            String id = (String) article.get("id");
            ArticleAdEnum flag = ArticleAdEnum.valueOf(articleDto.getAdOption());
            ClientTypeEnum clientType = ClientTypeEnum.wechat;
            switch (flag) {
                case BANNER:
                    resolve = section.getPayForBannerResolve();
                    if (section.getPayForBanner() == 1  && resolve.getPrice(resolveKey) != null && resolve.getPrice(resolveKey).doubleValue() > 0) {
                        OrderArticleAd order = orderService.addArticleAdOrder(id, resolve.getPrice(resolveKey), flag, SectionPayResolve.getStartTime(resolveKey), SectionPayResolve.getEndTime(resolveKey));
                        Object prepayResult = orderService.prePayOrder(order.getId() + "", clientType, ProductTypeEnum.FORUM_AD, request);
                        data.put("data", prepayResult);
                        data.put("total", order.getTotal());
                    } else {
                        //不需要支付，直接增加标记
                        articleService.addFlag(id, flag, resolve.getStartTime(resolveKey), resolve.getEndTime(resolveKey));
                    }
                    break;
                case LIST_TOP:
                    resolve = section.getPayForTopResolve();
                    if (section.getPayForTop() == 1 && resolve.getPrice(resolveKey) != null && resolve.getPrice(resolveKey).doubleValue() > 0) {
                        OrderArticleAd order = orderService.addArticleAdOrder(id, resolve.getPrice(resolveKey), flag, SectionPayResolve.getStartTime(resolveKey), SectionPayResolve.getEndTime(resolveKey));
                        Object prepayResult = orderService.prePayOrder(order.getId() + "", clientType, ProductTypeEnum.FORUM_AD, request);
                        data.put("total", order.getTotal());
                        data.put("data", prepayResult);
                    } else {
                        //不需要支付，直接增加标记
                        articleService.addFlag(id, flag, resolve.getStartTime(resolveKey), resolve.getEndTime(resolveKey));
                    }
                    break;
                default:
                    throw new BizException("参数错误!");
            }


            data.put("article", article);
            res.put("data", data);
            this.success(res);
        } catch (BizException ex) {
            this.failed(res, ex);
        }
        return JSON.toJSONString(res);
    }


    /**
     * 删除用户文章
     *
     * @param articleId
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "user/del/Article", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public Map userDelArticle(@RequestParam(value = "articleId", required = true) String articleId) throws Exception {
        Map<String, Object> res = new HashedMap();
        try {
            NeiyiUser user = (NeiyiUser) getCurrentUser();
            articleService.deleteUserArticle(user, articleId);
            this.success(res);
        } catch (BizException ex) {
            this.failed(res, ex);
        }
        return res;
    }


    /***
     * 评论图文文章
     * @param articleComment
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "/commentArticle")
    public Map commentArticle(@RequestBody ArticleComment articleComment) throws Exception {
        HashMap res = new HashMap();
        try {
            NeiyiUser user = (NeiyiUser) getCurrentUser();
            articleComment.setUser_id(user.getId());
            articleComment.setUser_nickname(CommonUtils.isEmpty(user.getCompanyName()) ? "" : user.getCompanyName());
            articleComment.setUser_head_img_url(CommonUtils.isEmpty(user.getUserLogo()) ? "" : user.getUserLogo());
            DBObject dbObject = articleService.commentArticle(articleComment);
            res.put("data", dbObject);
            this.success(res);
        } catch (BizException ex) {
            this.failed(res, ex);
        }
        return res;
    }

    /**
     * @param article_id
     * @param content
     * @param to_user_id
     * @param modelMap
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "addComment", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String addComment(String article_id, String content, String to_user_id, ModelMap modelMap) throws Exception {
        modelMap.clear();
        try {
            ArticleComment articleComment = new ArticleComment();
            NeiyiUser user = (NeiyiUser) getCurrentUser();
            articleComment.setUser_id(user.getId());
            articleComment.setUser_nickname(CommonUtils.isEmpty(user.getCompanyName()) ? "" : user.getCompanyName());
            articleComment.setUser_head_img_url(CommonUtils.isEmpty(user.getUserLogo()) ? "" : user.getUserLogo());
            articleComment.setContent(content);
            articleComment.setArticle_id(article_id);
            articleComment.setTo_user_id(to_user_id);
            DBObject dbObject = articleService.commentArticle(articleComment);
            modelMap.put("data", dbObject);
            this.success(modelMap);
        } catch (BizException ex) {
            this.failed(modelMap, ex);
        }
        return JSON.toJSONString(modelMap);
    }

    /**
     * @param article_id
     * @param flag
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "articleCollect", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public Map articleCollect(String article_id, boolean flag) {
        Map res = new HashMap();
        try {
            articleService.articleCollect(article_id, flag);
            res.put("flag", true);
            this.success(res);
        } catch (BizException ex) {
            LOGGER.error("发生错误:", ex);
            this.failed(res, ex.getMessage());
        } catch (Exception ex) {
            LOGGER.error("发生异常", ex);
            this.failed(res, "服务器发生了未知的错误，请联系管理员或者开发者解决!");
        }
        return res;
    }

    /**
     * 获取评论列表
     *
     * @param pageNum
     * @param pageSize
     * @param article_id
     * @param modelMap
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "getCommentsList", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String getCommentsList(@RequestParam(value = "pageNum", required = true) Integer pageNum,
                                  @RequestParam(value = "pageSize", required = true) Integer pageSize,
                                  @RequestParam(value = "type", required = true) Integer type,
                                  @RequestParam(value = "article_id", required = true) String article_id, ModelMap modelMap) throws Exception {
        modelMap.clear();
        try {
            Map<String, Object> data = new HashedMap();
            List<DBObject> comments = articleService.getCommentsList(pageSize, pageNum, article_id, type);
            Long total = articleService.countComments(article_id, type);
            data.put("comments", comments);
            data.put("total", total);
            modelMap.put("data", data);
            this.success(modelMap);
        } catch (BizException ex) {
            this.failed(modelMap, ex);
        }
        return JSON.toJSONString(modelMap);
    }

    /**
     * 获取图文文章详情
     *
     * @param article_id
     * @param modelMap
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "getArticleInfo", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String getArticleInfo(@RequestParam(value = "article_id", required = true) String article_id, ModelMap modelMap) throws Exception {
        modelMap.clear();
        try {
            DBObject articleInfo = articleService.getArticleInfo(article_id);
            modelMap.put("data", articleInfo);
            this.success(modelMap);
        } catch (BizException ex) {
            this.failed(modelMap, ex);
        }
        return JSON.toJSONString(modelMap);
    }

    @ResponseBody
    @RequestMapping(value = "myArticle", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String myArticle(@RequestParam(value = "pageNum", required = true) Integer pageNum,
                            @RequestParam(value = "pageSize", required = true) Integer pageSize, ModelMap modelMap) throws Exception {

        Map<String, Object> params = new HashedMap();
        params.put("uuid", getCurrentUserId());

        List<DBObject> articles = articleService.getArticleForPage(params, pageSize, pageNum);

        modelMap.put("data", articles);
        this.success(modelMap);
        return JSON.toJSONString(modelMap);
    }


    @ResponseBody
    @RequestMapping("/delArticle")
    public Map delArticle(String articleId) {
        Map res = new HashMap();
        try {
            if (StringUtils.isEmpty(articleId)) {
                throw new BizException("未找到文章信息，删除失败!");
            }

            DBObject article = articleService.getArticleInfo(articleId);
            Long userId = (Long) article.get("uuid");
            if (CurrentRequest.getCurrentUserId() != userId) {
                throw new BizException("您没有删除此文章的权限，文章不属于您！");
            }

            MCondition delMc = MCondition.create(MRel.and);
            delMc.append("id", articleId);
            delMc.append("uuid", userId);

            articleService.deleteInfoArticle(delMc.toDBObject());
            this.success(res);
        } catch (BizException ex) {
            LOGGER.error("occur business error", ex);
            this.failed(res, ex.getMessage());
        } catch (Exception ex) {
            LOGGER.error("occur un-expected error", ex);
            this.failed(res, "服务器发生未知错误，请稍后再试或者联系管理员解决！");
        }
        return res;
    }


}
